package ute.mvc.controller.portal.student;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import ute.mvc.dto.SubmittedTestDTO;
import ute.mvc.model.MyClass;
import ute.mvc.model.OpenCourse;
import ute.mvc.model.OpenCourse_Subject;
import ute.mvc.model.SubmittedTestAndQuizz;
import ute.mvc.model.TestAndQuizz;
import ute.mvc.model.TestAndQuizz_Student;
import ute.mvc.model.User;
import ute.mvc.service.ClassService;
import ute.mvc.service.Course_SubjectService;
import ute.mvc.service.OpenCourseService;
import ute.mvc.service.SubmittedTestAndQuizzService;
import ute.mvc.service.TestAndQuizzService;
import ute.mvc.service.TestAndQuizz_StudentService;
import ute.mvc.service.UserService;
import ute.mvc.util.JsonObject;

import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
@RequestMapping(value = { "/student/{studentId}/{openCourseId}/{subjectId}/test" })
public class StudentTestController {

	@Autowired
	UserService userService;
	@Autowired
	OpenCourseService openCourseService;
	@Autowired
	ClassService classService;
	@Autowired
	Course_SubjectService courseSubjectService;
	@Autowired
	TestAndQuizzService testService;
	@Autowired
	TestAndQuizz_StudentService testAndQuizz_StudentService;
	@Autowired
	SubmittedTestAndQuizzService submittedService;

	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String getTestList(@PathVariable String openCourseId,
			@PathVariable String subjectId, Model model) {

		System.out.println("List Test: ");
		return "student_test_list";
	}

	@RequestMapping(value = "/{testId}/", method = RequestMethod.GET)
	public String getTestDetail(@PathVariable int studentId,
			@PathVariable String testId, @PathVariable String openCourseId,
			@PathVariable String subjectId, Model model) {
		// Show Begin Test
		boolean flagTest = false;

		TestAndQuizz test = testService.getTestAndQuizz(testId);
		TestAndQuizz_Student testAndQuizzStudent = testAndQuizz_StudentService
				.getTestAndQuizz_Student(testId + "_" + studentId);
		System.out.println(testAndQuizzStudent.getListSubmittedTestAndQuizz().size());
		System.out.println(testAndQuizzStudent
						.getTestAndQuizz().getSubmitTimeAllow());
		if(testAndQuizzStudent != null && testAndQuizzStudent.getListSubmittedTestAndQuizz().size() >= testAndQuizzStudent
						.getTestAndQuizz().getSubmitTimeAllow()){
			flagTest = true;
		}
		if (test.getEndDay().after(new Date())) {
			flagTest = true;
		}
		model.addAttribute("test", test);
		model.addAttribute("flagTest", flagTest);
		System.out.println("List Test Detail: ");
		return "student_test_detail";
	}

	@RequestMapping(value = "/feedback/{submittedTestId}", method = RequestMethod.GET)
	public String getTestFeedBack(@PathVariable String submittedTestId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			Model model) {

		SubmittedTestAndQuizz submitted = submittedService
				.getSubmittedTestAndQuizz(submittedTestId);
		String feedBack = submitted.getExamQuestion();
		// Parse feedback to TestAndQuizz Object

		// Add to test model and send to feedback

		TestAndQuizz test = new TestAndQuizz();
		model.addAttribute("test", test);
		// Get Question in TestPart
		return "student_test_feedback";
	}

	@RequestMapping(value = "/{testId}/test", method = RequestMethod.GET)
	public String getTest(@PathVariable int studentId,
			@PathVariable String testId, @PathVariable String openCourseId,
			@PathVariable String subjectId, Model model) {

		System.out.println("Test Test: ");
		// Begin Test
		// If current in test time, return the test in process
		TestAndQuizz test = testService.getTestAndQuizz(testId);
		if (test.getEndDay().before(new Date())) {
			// Out of time
			System.out.println("Out of time");
			return "redirect:";
		}
		int testNumber = 0;

		TestAndQuizz_Student testAndQuizzStudent = testAndQuizz_StudentService
				.getTestAndQuizz_Student(testId + "_" + studentId);
		if (testAndQuizzStudent == null) {
			// Create new Test_Student
			testAndQuizzStudent = new TestAndQuizz_Student();
			testAndQuizzStudent.setTestAndQuizz_StudentId(testId + "_"
					+ studentId);
			User student = userService.getUserById(studentId);
			testAndQuizzStudent.setStudent(student);
			testAndQuizzStudent.setTestAndQuizz(test);
			testAndQuizz_StudentService
					.addTestAndQuizz_Student(testAndQuizzStudent);
		} else {
			// Load Test_Student
		}
		testNumber = testAndQuizzStudent.getListSubmittedTestAndQuizz().size();
		if (testNumber >= testAndQuizzStudent.getTestAndQuizz()
				.getSubmitTimeAllow()) {
			System.out.println("Over Submitted");
			return "redirect:";
		}
		SubmittedTestAndQuizz submittedTest = new SubmittedTestAndQuizz();
		submittedTest.setTestAndQuizz_student(testAndQuizzStudent);

		ObjectMapper map = new ObjectMapper();
		return "student_test_process";
	}

	/**
	 * Get All Test & Quizz for concrete Test
	 * 
	 * @param studentId
	 * @param openCourseId
	 * @param subjectId
	 * @param model
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "/{testId}/listJSON", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject getTestListDetailJson(@PathVariable String testId,
			@PathVariable int studentId, @PathVariable String openCourseId,
			@PathVariable String subjectId, Model model) {

		User student = userService.getUserById(studentId);
		// Has not start test => null in testAndQuizzStudent
		TestAndQuizz_Student testAndQuizzStudent = testService
				.getTestAndQuizzByStudent(student, testId);
		List<SubmittedTestDTO> lstSubmittedTest = new ArrayList<SubmittedTestDTO>();

		// hasn't start test ==> empty SubmittedTest
		if (testAndQuizzStudent != null) {
			for (SubmittedTestAndQuizz s : testAndQuizzStudent
					.getListSubmittedTestAndQuizz()) {
				lstSubmittedTest.add(new SubmittedTestDTO(s));
			}
		}

		JsonObject jsonObject = new JsonObject();
		jsonObject.setAaData(lstSubmittedTest);
		jsonObject.setsEcho(1);
		jsonObject.setiTotalDisplayRecords(lstSubmittedTest.size());
		jsonObject.setiTotalRecords(lstSubmittedTest.size());
		return jsonObject;
	}

	/**
	 * List All Test Assigned For Student
	 * 
	 * @param studentId
	 * @param openCourseId
	 * @param subjectId
	 * @param model
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "/listJSON", method = RequestMethod.GET)
	@ResponseBody
	public JsonObject getTestListJson(@PathVariable int studentId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			Model model) {

		User student = userService.getUserById(studentId);
		OpenCourse oCourse = openCourseService.getOpenCourseById(openCourseId);
		MyClass uClass = openCourseService.getClass(student, oCourse);
		OpenCourse_Subject oCourseSubject = courseSubjectService
				.getCourse_Subject(openCourseId + "_" + subjectId);
		List<TestAndQuizz> lstTest = classService
				.getAllTestInOpenCourseSubject(oCourseSubject,
						uClass.getClassId());
		System.out.println(uClass.getClassName());
		System.out.println("List Test: " + lstTest.size());
		JsonObject jsonObject = new JsonObject();
		jsonObject.setAaData(lstTest);
		jsonObject.setsEcho(1);
		jsonObject.setiTotalDisplayRecords(lstTest.size());
		jsonObject.setiTotalRecords(lstTest.size());
		return jsonObject;
	}
}
